🎖️GitЯра🎖️
Node / meshtastic / Meshtastic-Android / files / androidApp / src / fdroid / kotlin / org / meshtastic / app / map / FdroidMapOverlayRenderer.kt
Displaying Raw • Download
androidApp/src/fdroid/kotlin/org/meshtastic/app/map/FdroidMapOverlayRenderer.kt 9d416855dd1d2074b5dbb5ad40e7e954246afcdf (9d416855) Text, 9.20 KB
T8b949e/*
* Copyright (c) 2026 Meshtastic LLC
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
Tff7b72package T7ee787org.meshtastic.app.map
Tff7b72import T7ee787android.graphics.Color
Tff7b72import T7ee787androidx.core.graphics.toColorInt
Tff7b72import T7ee787co.touchlab.kermit.Logger
Tff7b72import T7ee787kotlinx.coroutines.Dispatchers
Tff7b72import T7ee787kotlinx.coroutines.withContext
Tff7b72import T7ee787org.meshtastic.app.map.cluster.RadiusMarkerClusterer
Tff7b72import T7ee787org.osmdroid.bonuspack.kml.KmlDocument
Tff7b72import T7ee787org.osmdroid.bonuspack.kml.KmlFeature
Tff7b72import T7ee787org.osmdroid.bonuspack.kml.KmlLineString
Tff7b72import T7ee787org.osmdroid.bonuspack.kml.KmlPlacemark
Tff7b72import T7ee787org.osmdroid.bonuspack.kml.KmlPoint
Tff7b72import T7ee787org.osmdroid.bonuspack.kml.KmlPolygon
Tff7b72import T7ee787org.osmdroid.bonuspack.kml.KmlTrack
Tff7b72import T7ee787org.osmdroid.views.MapView
Tff7b72import T7ee787org.osmdroid.views.overlay.Marker
Tff7b72import T7ee787org.osmdroid.views.overlay.Overlay
Tff7b72import T7ee787org.osmdroid.views.overlay.Polygon
Tff7b72import T7ee787org.osmdroid.views.overlay.Polyline
Tff7b72import T7ee787java.io.InputStream
Tff7b72import T7ee787kotlin.math.roundToInt
Tff7b72private Tff7b72const Tff7b72val Te6edf3TAG Tff7b72= Ta5d6ff"Ta5d6ffMapOverlayRendererTa5d6ff"
T8b949e// simplestyle-spec fallbacks, mirroring the Google flavor's applySimpleStyleSpec(); tune here.
Tff7b72private Tff7b72const Tff7b72val Te6edf3DEFAULT_GEOJSON_FILL_OPACITY Tff7b72= T79c0ff0.35f
Tff7b72private Tff7b72const Tff7b72val Te6edf3DEFAULT_GEOJSON_STROKE_WIDTH Tff7b72= T79c0ff2f
Tff7b72private Tff7b72const Tff7b72val Te6edf3OPAQUE Tff7b72= T79c0ff2T79c0ff5T79c0ff5
T8b949e/**
* F-Droid flavor's map-overlay renderer: turns the shared [MapLayerItem] list into OSMdroid overlays via osmbonuspack's
* [KmlDocument], honoring per-feature mapbox **simplestyle** (`fill`/`stroke`/`fill-opacity`/`stroke-width`) so
* imported coverage draws in its dBm colors — the OSMdroid mirror of the Google flavor's
* `GeoJsonLayer.applySimpleStyleSpec()`.
*
* A single instance is kept for the lifetime of the map composable. [reconcile] is called whenever the layer list
* changes; it adds newly-visible layers, removes gone/hidden ones, and rebuilds any whose URI or refresh flag changed.
*/
Tff7b72class T56d364FdroidMapOverlayRenderer Tb4b4b4{
Tff7b72private Tff7b72data Tff7b72class T56d364RenderedTb4b4b4(Tff7b72val Te6edf3signatureTb4b4b4: Tffa657StringTb4b4b4, Tff7b72val Te6edf3overlayTb4b4b4: Te6edf3OverlayTb4b4b4)
T8b949e// id -> currently-drawn overlay. Touched only from reconcile()'s (single-flight) coroutine.
Tff7b72private Tff7b72val Te6edf3rendered Tff7b72= Te6edf3mutableMapOfTff7b72<Tffa657StringTb4b4b4, Te6edf3RenderedTff7b72>Tb4b4b4(Tb4b4b4)
Tff7b72private Tff7b72fun Td2a8ffsignatureOfTb4b4b4(Te6edf3itemTb4b4b4: Te6edf3MapLayerItemTb4b4b4) Tff7b72= Ta5d6ff"Tffd700${Te6edf3itemTb4b4b4.Te6edf3uriTffd700}Ta5d6ff|Tffd700${Te6edf3itemTb4b4b4.Te6edf3refreshTokenTffd700}Ta5d6ff"
T8b949e/** Reconcile the map's overlays with [layers]. [openStream] resolves a layer to its data (file or network). */
Tff7b72suspend Tff7b72fun Td2a8ffreconcileTb4b4b4(
Te6edf3mapTb4b4b4: Te6edf3MapViewTb4b4b4,
Te6edf3layersTb4b4b4: Te6edf3ListTff7b72<Te6edf3MapLayerItemTff7b72>Tb4b4b4,
Te6edf3openStreamTb4b4b4: Te6edf3suspend Tb4b4b4(Te6edf3MapLayerItemTb4b4b4) Tff7b72-Tff7b72> Te6edf3InputStream?Tb4b4b4,
Tb4b4b4) Tb4b4b4{
Tff7b72val Te6edf3visible Tff7b72= Te6edf3layersTb4b4b4.Te6edf3filter Tb4b4b4{ Tffa657itTb4b4b4.Te6edf3isVisible Tff7b72&Tff7b72& Tffa657itTb4b4b4.Te6edf3uri Tff7b72!Tff7b72= Tff7b72null Tb4b4b4}
Tff7b72val Te6edf3wanted Tff7b72= Te6edf3visibleTb4b4b4.Te6edf3associateBy Tb4b4b4{ Tffa657itTb4b4b4.Te6edf3id Tb4b4b4}
Tff7b72var Te6edf3dirty Tff7b72= Tff7b72false
T8b949e// Drop overlays that are gone, hidden, or whose signature changed (rebuild).
Tff7b72val Te6edf3stale Tff7b72= Te6edf3renderedTb4b4b4.Te6edf3filter Tb4b4b4{ Tb4b4b4(Te6edf3idTb4b4b4, Te6edf3rTb4b4b4) Tff7b72-Tff7b72> Te6edf3wantedTff7b72[Te6edf3idTff7b72]Tff7b72?.Te6edf3let Tb4b4b4{ Te6edf3signatureOfTb4b4b4(Tffa657itTb4b4b4) Tff7b72=Tff7b72= Te6edf3rTb4b4b4.Te6edf3signature Tb4b4b4} Tff7b72!Tff7b72= Tff7b72true Tb4b4b4}
Tff7b72if Tb4b4b4(Te6edf3staleTb4b4b4.Te6edf3isNotEmptyTb4b4b4(Tb4b4b4)Tb4b4b4) Tb4b4b4{
Te6edf3withContextTb4b4b4(Te6edf3DispatchersTb4b4b4.Te6edf3MainTb4b4b4.Te6edf3immediateTb4b4b4) Tb4b4b4{ Te6edf3staleTb4b4b4.Te6edf3valuesTb4b4b4.Te6edf3forEach Tb4b4b4{ Te6edf3mapTb4b4b4.Te6edf3overlaysTb4b4b4.Te6edf3removeTb4b4b4(Tffa657itTb4b4b4.Te6edf3overlayTb4b4b4) Tb4b4b4} Tb4b4b4}
Te6edf3staleTb4b4b4.Te6edf3keysTb4b4b4.Te6edf3forEach Tb4b4b4{ Te6edf3renderedTb4b4b4.Te6edf3removeTb4b4b4(Tffa657itTb4b4b4) Tb4b4b4}
Te6edf3dirty Tff7b72= Tff7b72true
Tb4b4b4}
T8b949e// Build overlays for visible layers not already drawn.
Tff7b72for Tb4b4b4(Te6edf3layer Tff7b72in Te6edf3visibleTb4b4b4) Tb4b4b4{
Tff7b72if Tb4b4b4(Te6edf3renderedTb4b4b4.Te6edf3containsKeyTb4b4b4(Te6edf3layerTb4b4b4.Te6edf3idTb4b4b4)Tb4b4b4) Tff7b72continue
Tff7b72val Te6edf3doc Tff7b72= Te6edf3parseTb4b4b4(Te6edf3layerTb4b4b4, Te6edf3openStreamTb4b4b4) Tff7b72?: Tff7b72continue
Tff7b72val Te6edf3overlay Tff7b72=
Te6edf3withContextTb4b4b4(Te6edf3DispatchersTb4b4b4.Te6edf3MainTb4b4b4.Te6edf3immediateTb4b4b4) Tb4b4b4{
T8b949e// Build on the main thread: overlay markers reference the MapView (info windows, defaults).
Te6edf3docTb4b4b4.Te6edf3mKmlRootTb4b4b4.Te6edf3buildOverlayTb4b4b4(Te6edf3mapTb4b4b4, Tff7b72nullTb4b4b4, Te6edf3SimpleStyleStylerTb4b4b4, Te6edf3docTb4b4b4)Tb4b4b4.Te6edf3also Tb4b4b4{ Te6edf3insertBelowMarkersTb4b4b4(Te6edf3mapTb4b4b4, Tffa657itTb4b4b4) Tb4b4b4}
Tb4b4b4}
Te6edf3renderedTff7b72[Te6edf3layerTb4b4b4.Te6edf3idTff7b72] Tff7b72= Te6edf3RenderedTb4b4b4(Te6edf3signatureOfTb4b4b4(Te6edf3layerTb4b4b4)Tb4b4b4, Te6edf3overlayTb4b4b4)
Te6edf3dirty Tff7b72= Tff7b72true
Tb4b4b4}
Tff7b72if Tb4b4b4(Te6edf3dirtyTb4b4b4) Te6edf3withContextTb4b4b4(Te6edf3DispatchersTb4b4b4.Te6edf3MainTb4b4b4.Te6edf3immediateTb4b4b4) Tb4b4b4{ Te6edf3mapTb4b4b4.Te6edf3invalidateTb4b4b4(Tb4b4b4) Tb4b4b4}
Tb4b4b4}
T8b949e/**
* Remove every layer overlay. Call on the main thread (e.g. from onDispose); the OSMdroid map outlives composition.
*/
Tff7b72fun Td2a8ffremoveAllTb4b4b4(Te6edf3mapTb4b4b4: Te6edf3MapViewTb4b4b4) Tb4b4b4{
Tff7b72if Tb4b4b4(Te6edf3renderedTb4b4b4.Te6edf3isEmptyTb4b4b4(Tb4b4b4)Tb4b4b4) Tff7b72return
Te6edf3renderedTb4b4b4.Te6edf3valuesTb4b4b4.Te6edf3forEach Tb4b4b4{ Te6edf3mapTb4b4b4.Te6edf3overlaysTb4b4b4.Te6edf3removeTb4b4b4(Tffa657itTb4b4b4.Te6edf3overlayTb4b4b4) Tb4b4b4}
Te6edf3renderedTb4b4b4.Te6edf3clearTb4b4b4(Tb4b4b4)
Te6edf3mapTb4b4b4.Te6edf3invalidateTb4b4b4(Tb4b4b4)
Tb4b4b4}
Tff7b72private Tff7b72suspend Tff7b72fun Td2a8ffparseTb4b4b4(Te6edf3layerTb4b4b4: Te6edf3MapLayerItemTb4b4b4, Te6edf3openStreamTb4b4b4: Te6edf3suspend Tb4b4b4(Te6edf3MapLayerItemTb4b4b4) Tff7b72-Tff7b72> Te6edf3InputStream?Tb4b4b4)Tb4b4b4: Te6edf3KmlDocument? Tb4b4b4{
Tff7b72val Te6edf3stream Tff7b72= Te6edf3openStreamTb4b4b4(Te6edf3layerTb4b4b4) Tff7b72?: Tff7b72return Tff7b72null
Tff7b72return Te6edf3withContextTb4b4b4(Te6edf3DispatchersTb4b4b4.Te6edf3IOTb4b4b4) Tb4b4b4{
Tff7b72try Tb4b4b4{
Tff7b72val Te6edf3doc Tff7b72= Te6edf3KmlDocumentTb4b4b4(Tb4b4b4)
Tff7b72val Te6edf3ok Tff7b72=
Te6edf3streamTb4b4b4.Te6edf3use Tb4b4b4{ Te6edf3input Tff7b72-Tff7b72>
Tff7b72when Tb4b4b4(Te6edf3layerTb4b4b4.Te6edf3layerTypeTb4b4b4) Tb4b4b4{
Te6edf3LayerTypeTb4b4b4.Te6edf3GEOJSONTb4b4b4,
Te6edf3LayerTypeTb4b4b4.Te6edf3COVERAGETb4b4b4,
Tff7b72-Tff7b72> Te6edf3docTb4b4b4.Te6edf3parseGeoJSONTb4b4b4(Te6edf3inputTb4b4b4.Te6edf3bufferedReaderTb4b4b4(Tb4b4b4)Tb4b4b4.Te6edf3readTextTb4b4b4(Tb4b4b4)Tb4b4b4)
Te6edf3LayerTypeTb4b4b4.Te6edf3KML Tff7b72-Tff7b72> Te6edf3docTb4b4b4.Te6edf3parseKMLStreamTb4b4b4(Te6edf3inputTb4b4b4, Tff7b72nullTb4b4b4)
Tb4b4b4}
Tb4b4b4}
Tff7b72if Tb4b4b4(Te6edf3okTb4b4b4) Te6edf3doc Tff7b72else Tff7b72null
Tb4b4b4} Tff7b72catch Tb4b4b4(Te6edf3eTb4b4b4: Te6edf3ExceptionTb4b4b4) Tb4b4b4{
Te6edf3LoggerTb4b4b4.Te6edf3withTagTb4b4b4(Te6edf3TAGTb4b4b4)Tb4b4b4.Te6edf3eTb4b4b4(Te6edf3eTb4b4b4) Tb4b4b4{ Ta5d6ff"Ta5d6ffError parsing map layer: Tffd700${Te6edf3layerTb4b4b4.Te6edf3nameTffd700}Ta5d6ff" Tb4b4b4}
Tff7b72null
Tb4b4b4}
Tb4b4b4}
Tb4b4b4}
T8b949e// Keep coverage under the node markers/clusterer so nodes stay visible + tappable (matching the Google flavor).
Tff7b72private Tff7b72fun Td2a8ffinsertBelowMarkersTb4b4b4(Te6edf3mapTb4b4b4: Te6edf3MapViewTb4b4b4, Te6edf3overlayTb4b4b4: Te6edf3OverlayTb4b4b4) Tb4b4b4{
Tff7b72val Te6edf3idx Tff7b72= Te6edf3mapTb4b4b4.Te6edf3overlaysTb4b4b4.Te6edf3indexOfFirst Tb4b4b4{ Tffa657it Tff7b72is Te6edf3RadiusMarkerClusterer Tff7b72|Tff7b72| Tffa657it Tff7b72is Te6edf3Marker Tb4b4b4}
Tff7b72if Tb4b4b4(Te6edf3idx Tff7b72>Tff7b72= T79c0ff0Tb4b4b4) Te6edf3mapTb4b4b4.Te6edf3overlaysTb4b4b4.Te6edf3addTb4b4b4(Te6edf3idxTb4b4b4, Te6edf3overlayTb4b4b4) Tff7b72else Te6edf3mapTb4b4b4.Te6edf3overlaysTb4b4b4.Te6edf3addTb4b4b4(Te6edf3overlayTb4b4b4)
Tb4b4b4}
Tb4b4b4}
T8b949e/**
* osmbonuspack styler that maps mapbox simplestyle properties (read from a GeoJSON feature's `properties`, which
* osmbonuspack stores as KML ExtendedData) onto the built osmdroid geometry. Only overrides when a property is present,
* so KML files keep their own `<Style>`.
*/
Tff7b72private Tff7b72object T56d364SimpleStyleStyler Tb4b4b4: Te6edf3KmlFeatureTb4b4b4.Te6edf3Styler Tb4b4b4{
Tff7b72override Tff7b72fun Td2a8ffonFeatureTb4b4b4(Te6edf3overlayTb4b4b4: Te6edf3Overlay?Tb4b4b4, Te6edf3kmlFeatureTb4b4b4: Te6edf3KmlFeature?Tb4b4b4) Tff7b72= Tffa657Unit
Tff7b72override Tff7b72fun Td2a8ffonPointTb4b4b4(Te6edf3markerTb4b4b4: Te6edf3Marker?Tb4b4b4, Te6edf3kmlPlacemarkTb4b4b4: Te6edf3KmlPlacemark?Tb4b4b4, Te6edf3kmlPointTb4b4b4: Te6edf3KmlPoint?Tb4b4b4) Tff7b72= Tffa657Unit
Tff7b72override Tff7b72fun Td2a8ffonLineStringTb4b4b4(Te6edf3polylineTb4b4b4: Te6edf3Polyline?Tb4b4b4, Te6edf3kmlPlacemarkTb4b4b4: Te6edf3KmlPlacemark?Tb4b4b4, Te6edf3kmlLineStringTb4b4b4: Te6edf3KmlLineString?Tb4b4b4) Tb4b4b4{
Te6edf3polyline Tff7b72?: Tff7b72return
Tff7b72val Te6edf3stroke Tff7b72= Te6edf3kmlPlacemarkTff7b72?.Te6edf3cssColorTb4b4b4(Ta5d6ff"Ta5d6ffstrokeTa5d6ff"Tb4b4b4) Tff7b72?: Te6edf3kmlPlacemarkTff7b72?.Te6edf3cssColorTb4b4b4(Ta5d6ff"Ta5d6ffcolorTa5d6ff"Tb4b4b4)
Te6edf3strokeTff7b72?.Te6edf3let Tb4b4b4{ Te6edf3polylineTb4b4b4.Te6edf3color Tff7b72= Tffa657it Tb4b4b4}
Te6edf3kmlPlacemarkTff7b72?.Te6edf3getExtendedDataTb4b4b4(Ta5d6ff"Ta5d6ffstroke-widthTa5d6ff"Tb4b4b4)Tff7b72?.Te6edf3toFloatOrNullTb4b4b4(Tb4b4b4)Tff7b72?.Te6edf3let Tb4b4b4{ Te6edf3polylineTb4b4b4.Te6edf3width Tff7b72= Tffa657it Tb4b4b4}
Tb4b4b4}
Tff7b72override Tff7b72fun Td2a8ffonPolygonTb4b4b4(Te6edf3polygonTb4b4b4: Te6edf3Polygon?Tb4b4b4, Te6edf3kmlPlacemarkTb4b4b4: Te6edf3KmlPlacemark?Tb4b4b4, Te6edf3kmlPolygonTb4b4b4: Te6edf3KmlPolygon?Tb4b4b4) Tb4b4b4{
Te6edf3polygon Tff7b72?: Tff7b72return
Tff7b72val Te6edf3fill Tff7b72= Te6edf3kmlPlacemarkTff7b72?.Te6edf3cssColorTb4b4b4(Ta5d6ff"Ta5d6fffillTa5d6ff"Tb4b4b4) Tff7b72?: Te6edf3kmlPlacemarkTff7b72?.Te6edf3cssColorTb4b4b4(Ta5d6ff"Ta5d6ffcolorTa5d6ff"Tb4b4b4)
Tff7b72val Te6edf3stroke Tff7b72= Te6edf3kmlPlacemarkTff7b72?.Te6edf3cssColorTb4b4b4(Ta5d6ff"Ta5d6ffstrokeTa5d6ff"Tb4b4b4) Tff7b72?: Te6edf3kmlPlacemarkTff7b72?.Te6edf3cssColorTb4b4b4(Ta5d6ff"Ta5d6ffcolorTa5d6ff"Tb4b4b4)
Tff7b72val Te6edf3fillOpacity Tff7b72= Te6edf3kmlPlacemarkTff7b72?.Te6edf3getExtendedDataTb4b4b4(Ta5d6ff"Ta5d6fffill-opacityTa5d6ff"Tb4b4b4)Tff7b72?.Te6edf3toFloatOrNullTb4b4b4(Tb4b4b4)
Tff7b72val Te6edf3strokeWidth Tff7b72= Te6edf3kmlPlacemarkTff7b72?.Te6edf3getExtendedDataTb4b4b4(Ta5d6ff"Ta5d6ffstroke-widthTa5d6ff"Tb4b4b4)Tff7b72?.Te6edf3toFloatOrNullTb4b4b4(Tb4b4b4) Tff7b72?: Te6edf3DEFAULT_GEOJSON_STROKE_WIDTH
Te6edf3fillTff7b72?.Te6edf3let Tb4b4b4{ Te6edf3polygonTb4b4b4.Te6edf3fillColor Tff7b72= Tffa657itTb4b4b4.Te6edf3resolveFillAlphaTb4b4b4(Te6edf3fillOpacityTb4b4b4) Tb4b4b4}
Te6edf3strokeTff7b72?.Te6edf3let Tb4b4b4{ Te6edf3polygonTb4b4b4.Te6edf3strokeColor Tff7b72= Tffa657it Tb4b4b4}
Te6edf3polygonTb4b4b4.Te6edf3strokeWidth Tff7b72= Te6edf3strokeWidth
Tb4b4b4}
Tff7b72override Tff7b72fun Td2a8ffonTrackTb4b4b4(Te6edf3polylineTb4b4b4: Te6edf3Polyline?Tb4b4b4, Te6edf3kmlPlacemarkTb4b4b4: Te6edf3KmlPlacemark?Tb4b4b4, Te6edf3kmlTrackTb4b4b4: Te6edf3KmlTrack?Tb4b4b4) Tff7b72= Tffa657Unit
Tb4b4b4}
Tff7b72private Tff7b72fun Te6edf3KmlPlacemarkTb4b4b4.Td2a8ffcssColorTb4b4b4(Te6edf3keyTb4b4b4: Tffa657StringTb4b4b4)Tb4b4b4: Tffa657Int? Tff7b72= Te6edf3getExtendedDataTb4b4b4(Te6edf3keyTb4b4b4)Tff7b72?.Te6edf3let Tb4b4b4{ Te6edf3parseCssColorTb4b4b4(Tffa657itTb4b4b4) Tb4b4b4}
T8b949e/**
* Resolve a polygon fill's alpha: `fill-opacity` wins when present; otherwise keep any alpha the color already carries
* (`rgba()`/`#AARRGGBB`), falling back to [DEFAULT_GEOJSON_FILL_OPACITY] for opaque fills.
*/
Tff7b72private Tff7b72fun Te6edf3IntTb4b4b4.Td2a8ffresolveFillAlphaTb4b4b4(Te6edf3fillOpacityTb4b4b4: Tffa657Float?Tb4b4b4)Tb4b4b4: Tffa657Int Tff7b72= Tff7b72when Tb4b4b4{
Te6edf3fillOpacity Tff7b72!Tff7b72= Tff7b72null Tff7b72-Tff7b72> Te6edf3withAlphaTb4b4b4(Te6edf3fillOpacityTb4b4b4)
Te6edf3ColorTb4b4b4.Te6edf3alphaTb4b4b4(Tff7b72thisTb4b4b4) Tff7b72< Te6edf3OPAQUE Tff7b72-Tff7b72> Tff7b72this
Tff7b72else Tff7b72-Tff7b72> Te6edf3withAlphaTb4b4b4(Te6edf3DEFAULT_GEOJSON_FILL_OPACITYTb4b4b4)
Tb4b4b4}
T8b949e/** Parse a hex (`#RRGGBB`/`#AARRGGBB`), `rgb()/rgba()`, or named color to an ARGB int; null if invalid. */
Tff7b72private Tff7b72fun Td2a8ffparseCssColorTb4b4b4(Te6edf3rawTb4b4b4: Tffa657StringTb4b4b4)Tb4b4b4: Tffa657Int? Tb4b4b4{
Tff7b72val Te6edf3value Tff7b72= Te6edf3rawTb4b4b4.Te6edf3trimTb4b4b4(Tb4b4b4)
Tff7b72return Tff7b72try Tb4b4b4{
Tff7b72if Tb4b4b4(Te6edf3valueTb4b4b4.Te6edf3startsWithTb4b4b4(Ta5d6ff"Ta5d6ffrgbTa5d6ff"Tb4b4b4, Te6edf3ignoreCase Tff7b72= Tff7b72trueTb4b4b4)Tb4b4b4) Tb4b4b4{
Tff7b72val Te6edf3parts Tff7b72= Te6edf3valueTb4b4b4.Te6edf3substringAfterTb4b4b4(Ta5d6ff'('Tb4b4b4)Tb4b4b4.Te6edf3substringBeforeTb4b4b4(Ta5d6ff')'Tb4b4b4)Tb4b4b4.Te6edf3splitTb4b4b4(Ta5d6ff','Tb4b4b4)Tb4b4b4.Te6edf3map Tb4b4b4{ Tffa657itTb4b4b4.Te6edf3trimTb4b4b4(Tb4b4b4) Tb4b4b4}
Tff7b72if Tb4b4b4(Te6edf3partsTb4b4b4.Te6edf3size Tff7b72< T79c0ff3Tb4b4b4) Tff7b72return Tff7b72null
Tff7b72val Te6edf3alpha Tff7b72= Tff7b72if Tb4b4b4(Te6edf3partsTb4b4b4.Te6edf3size Tff7b72>Tff7b72= T79c0ff4Tb4b4b4) Tb4b4b4(Te6edf3partsTff7b72[T79c0ff3Tff7b72]Tb4b4b4.Te6edf3toFloatTb4b4b4(Tb4b4b4) Tff7b72* Te6edf3OPAQUETb4b4b4)Tb4b4b4.Te6edf3roundToIntTb4b4b4(Tb4b4b4) Tff7b72else Te6edf3OPAQUE
Te6edf3ColorTb4b4b4.Te6edf3argbTb4b4b4(Te6edf3alphaTb4b4b4, Te6edf3partsTff7b72[T79c0ff0Tff7b72]Tb4b4b4.Te6edf3toIntTb4b4b4(Tb4b4b4)Tb4b4b4, Te6edf3partsTff7b72[T79c0ff1Tff7b72]Tb4b4b4.Te6edf3toIntTb4b4b4(Tb4b4b4)Tb4b4b4, Te6edf3partsTff7b72[T79c0ff2Tff7b72]Tb4b4b4.Te6edf3toIntTb4b4b4(Tb4b4b4)Tb4b4b4)
Tb4b4b4} Tff7b72else Tb4b4b4{
Te6edf3valueTb4b4b4.Te6edf3toColorIntTb4b4b4(Tb4b4b4) T8b949e// #hex or named color
Tb4b4b4}
Tb4b4b4} Tff7b72catch Tb4b4b4(Te6edf3eTb4b4b4: Te6edf3IllegalArgumentExceptionTb4b4b4) Tb4b4b4{
Te6edf3LoggerTb4b4b4.Te6edf3withTagTb4b4b4(Te6edf3TAGTb4b4b4)Tb4b4b4.Te6edf3wTb4b4b4(Te6edf3eTb4b4b4) Tb4b4b4{ Ta5d6ff"Ta5d6ffUnparseable GeoJSON color: Tffd700$Te6edf3rawTa5d6ff" Tb4b4b4}
Tff7b72null
Tb4b4b4}
Tb4b4b4}
Tff7b72private Tff7b72fun Te6edf3IntTb4b4b4.Td2a8ffwithAlphaTb4b4b4(Te6edf3opacityTb4b4b4: Tffa657FloatTb4b4b4)Tb4b4b4: Tffa657Int Tff7b72=
Te6edf3ColorTb4b4b4.Te6edf3argbTb4b4b4(Tb4b4b4(Te6edf3opacityTb4b4b4.Te6edf3coerceInTb4b4b4(T79c0ff0fTb4b4b4, T79c0ff1fTb4b4b4) Tff7b72* Te6edf3OPAQUETb4b4b4)Tb4b4b4.Te6edf3roundToIntTb4b4b4(Tb4b4b4)Tb4b4b4, Te6edf3ColorTb4b4b4.Te6edf3redTb4b4b4(Tff7b72thisTb4b4b4)Tb4b4b4, Te6edf3ColorTb4b4b4.Te6edf3greenTb4b4b4(Tff7b72thisTb4b4b4)Tb4b4b4, Te6edf3ColorTb4b4b4.Te6edf3blueTb4b4b4(Tff7b72thisTb4b4b4)Tb4b4b4)
Served by rngit 1.5.0 - Generated in 0.08s